package com.changyou.kf.core.model;

import com.changyou.kf.core.exception.ErrorCode;
import com.changyou.kf.core.exception.GlobalErrorCode;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;

@SuppressWarnings("unchecked")
@Schema(description = "返回结果")
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
@AllArgsConstructor
@Data
public class R<T extends Object> {

    @Schema(description = "返回码")
    private int code;

    @Schema(description = "返回消息")
    private String msg;

    @Schema(description = "返回数据")
    private T data;

    public static R ok() {
        return build(GlobalErrorCode.OK, null);
    }

    public static <T> R ok(T data) {
        return build(GlobalErrorCode.OK, data);
    }

    public static <T> R isOk(Boolean ok) {
        return BooleanUtils.isTrue(ok) ? ok() : error();
    }

    public static R error() {
        return build(GlobalErrorCode.ERROR, null);
    }

    public static R error(ErrorCode errorCode) {
        return build(errorCode, null);
    }

    public static <T> R error(T data) {
        return build(GlobalErrorCode.ERROR, data);
    }

    public static <T> R error(ErrorCode errorCode, T data) {
        if (errorCode == null) {
            errorCode = GlobalErrorCode.ERROR;
        }
        return build(errorCode, data);
    }

    public static R error(ErrorCode errorCode, String msg) {
        if (errorCode == null) {
            errorCode = GlobalErrorCode.ERROR;
        }
        if (StringUtils.isEmpty(msg)) {
            msg = errorCode.getMsg();
        }
        return build(errorCode.getCode(), msg, null);
    }

    public static R error(String msg) {
        if (StringUtils.isEmpty(msg)) {
            msg = GlobalErrorCode.ERROR.getMsg();
        }
        return build(GlobalErrorCode.ERROR.getCode(), msg, null);
    }

    public static R error(int code, String msg) {
        return build(code, msg, null);
    }

    private static <T> R build(ErrorCode errorCode, T data) {
        return build(errorCode.getCode(), errorCode.getMsg(), data);
    }

    private static <T> R build(int code, String msg, T data) {
        return new R(code, msg, data);
    }
}
